#pragma once
#include <sys/queue.h>
#include "pthread.hpp"
#include "lockguard.hpp"
#include <queue>
#include <pthread.h>
#include <vector>
#include <unistd.h>
#include<functional>
// 引入自行封装的锁和线程创建,线程单例实现
#define NUM 5
class Task
{
public:
    using func_t = std::function<void(int,std::string,u_int16_t)>;
    Task()
    {
        ;
    }
    Task(int sock,std::string ip,uint16_t port,func_t func)
        : socket_(sock), ip_(ip), port_(port),func_(func)
    {
        ;
    }
    void operator()()
    {
        func_(socket_,ip_,port_);
    }
    int socket_;
    func_t func_;
    std::string ip_;
    u_int16_t port_;
};
template <class T>
class threadPool
{
    threadPool(int size = NUM) // vp_存的自定义类型要有默认构造,不然这里初始化会找不到默认构造!
        : vp_(size)
    {
        pthread_mutex_init(&mutex_, nullptr);
        pthread_cond_init(&Consumer, nullptr);
        pthread_cond_init(&Productor, nullptr);
    }
      ~threadPool()
    {
        for (auto &e : vp_) // 复用Thread join方法回收线程
        {
            e.join();
        }
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&Consumer);
        pthread_cond_destroy(&Productor);
    }
   threadPool(const threadPool<T>& sh) = delete;
	threadPool<T> operator=(const threadPool<T>& sh) = delete;
public:
    void init()
    {
        for (int i = 0; i < NUM; i++)
        {
            vp_[i] = (Thread(i, threadRun, this));//this指针是给内部传参数的
        }
    }
    void Lock()
    {
        pthread_mutex_lock(&mutex_);
    }
    void Unlock()
    {
        pthread_mutex_unlock(&mutex_);
    }
    static void *threadRun(void *arg)
    {
        // pthread_detach(pthread_self());
        threadPool<T> *tp = static_cast<threadPool<T> *>(arg);
        // 执行任务
        while (true)
        {
            T data;
            tp->pop(data);
            data();
        }
    }
    bool Full()
    {
        return tasks_.size() == NUM;
    }
    bool Empty()
    {
        return tasks_.size() == 0;
    }
    void start()
    {
        for (auto &e : vp_) // 复用Thread Run方法创建线程
        {
            e.Run();
        }
    }
  
    void push(const T &data)
    {
        {
            LockGuard lg(&mutex_);
            while (Full())
            {
                pthread_cond_wait(&Productor, &mutex_);
            }
            tasks_.push(data);
        }
        pthread_cond_signal(&Consumer);

    }
    void pop(T &data)
    {

        {
            LockGuard lg(&mutex_);
            // 检查是否有任务
            while (Empty())
            {
                pthread_cond_wait(&Consumer, &mutex_);
            }
            data = tasks_.front();
            tasks_.pop();
        }
        pthread_cond_signal(&Productor);
    }
    static threadPool<T>* getthreadPool()
    {
        if(tp_ == nullptr)//减少加锁次数
        {
            LockGuard lg(&Poolmutex_);
            if (tp_ == nullptr)
            {    
                tp_ = new threadPool<T>();
                tp_->init();
                tp_->start();
            }

        }
        return tp_;    
    }
    std::queue<T> tasks_;    // 任务队列
    std::vector<Thread> vp_; // 线程池,不能存指针,内部要解引用访问的
    pthread_mutex_t mutex_;
    pthread_cond_t Consumer;
    pthread_cond_t Productor;
    static threadPool<T>* tp_;
    static pthread_mutex_t Poolmutex_;
};
template<class T>
threadPool<T>*threadPool<T>::tp_ = nullptr;
template<class T>
pthread_mutex_t threadPool<T>::Poolmutex_ = PTHREAD_MUTEX_INITIALIZER;
